import { addParams } from "../utils/url";
import { isExternal, joinUrl, normalModule } from "../utils";
import jsLoader from "../utils/jsLoader";
import ReactDOM from "react-dom";
import React from "react";
import { debug } from "../utils/log";



export interface MicroAppProps {
    entry: string
    path: string
    publicPath?: string
    onLoad?: Function,
    onError?: Function,
    webComponents?: boolean
    [key: string]: any
}
const isOfflineEnv = (url: string) => {
    return url.includes('-dev') || url.includes('-test');
}
let version = +new Date()
const revise = (url: string): string => {

    if ((window as any).BUILD_VERSION) {
        url = addParams(url, `v=${(window as any).BUILD_VERSION}`)
    } else if (isOfflineEnv(url)) {
        url = addParams(url, `t=${version}`)
    }
    return url
}
class WebComponentsMicroApp extends HTMLElement {
    constructor() {
        super()
        const iRoot = this.attachShadow({ mode: 'open' })
        const div = document.createElement('div')
        // div.innerHTML='ss'
        iRoot.appendChild(div)
        // const style = document.createElement('style')
        // style.innerHTML = `div{
        //     background-color: red;
        //   }`
        //   iRoot.appendChild(style)
        // // document
    }
}
customElements.define('web-components-micro-app', WebComponentsMicroApp);
const withApp = (Component, cssUrl) => {
    const cssModule = Array.isArray(cssUrl) ? cssUrl : [cssUrl];
    return ({ ...rest }) => {
        return <>
            {cssModule.filter(Boolean).map(url => {
                return <link rel="stylesheet" href={url} />
            })}
            <Component {...rest} />
        </>
    }
}
const Spin = ({ spin, loading }) => {
    if (loading) {
        return <div className="micro-app-loading" style={{
            display: 'flex',
            position: 'absolute',
            width: '100%',
            left: 0,
            top: 0,
            height: '100%',
            justifyContent: 'center',
            alignItems: 'center'
        }}>
            {spin ? spin : 'loading...'}
        </div>
    }
    return null
}
const MicroApp = ({ spin, version, webComponents, path, onLoad, onError, entry, loadCss, publicPath, ...rest }: MicroAppProps) => {
    debug('MicroApp', entry, path)
    const [loading, setLoading] = React.useState(false)
    const el = React.useRef(null)
    const [appEl, setAppEl] = React.useState<any>(null);
    React.useEffect(() => {
        debug("load entry222", entry)

        if (!entry) {
            return
        }
        let appProps = {

        }
        if (rest.appProps) {
            Object.assign(appProps, rest.appProps)
        }
        if (!isExternal(entry)) {
            entry = joinUrl((publicPath) as string, entry)
        }
        let cssUrl = typeof loadCss === 'string' ? loadCss : (loadCss ? entry.replace('.js', '.css') : '');

        // if (version) {
        //     jsLoader([`react-dom-${version}`, `${revise(entry)}`])
        //         .then((modules: any[]) => {
        //             // const React = normalModule(modules[0])   
        //             const ReactDOM = normalModule(modules[0])
        //             const Component = withApp(normalModule(modules[1]), cssUrl)
        //             ReactDOM.render(<Component {...appProps} />, el.current.shadowRoot || el.current)

        //         })
        // } else {
        setLoading(true)
        jsLoader([revise(entry)])
            .then((modules: any[]) => {
                const Component = withApp(normalModule(modules[0]), cssUrl);

                // if (webComponents) {

                //     ReactDOM.render(<Component {...appProps} />, el.current.shadowRoot || el.current)
                // } else {

                setAppEl(<Component {...appProps} />);
                // }
            }, (err) => {
                debug('errr', err)
                setAppEl(<div>error</div>)
            })
            .finally(() => setLoading(false));
        // }

    }, [path, entry]);

    // if (webComponents) {
    //     //   @ts-ignore
    //     return <web-components-micro-app ref={el} />
    // }
    return <div style={{ height: '100%' }} data-entry={entry} className='micro-app-container' ref={el}>
        <Spin spin={spin} loading={loading} />
        {appEl}
    </div>
}
export default MicroApp